package com.aneliya.io.serializable;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;

import com.aneliya.io.IStreamStrategy;
import com.aneliya.model.Message;

public class SerializableStreamStrategy implements IStreamStrategy {
	
	private InputStream inputStream;
	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}

	private OutputStream outputStream;
	public void setOutputStream(OutputStream outputStream) {
		this.outputStream = outputStream;
	}
	
	public Message readMessage() throws IOException, SocketTimeoutException {
		try {
			Message message = (Message) objectInputStream.readObject();
			return message;
		} catch (ClassNotFoundException ex) {
			ex.printStackTrace();
		}
		return null;
	}

	public void writeMessage(Message message) throws IOException {
		try {
			objectOutputStream.writeObject(message);
			objectOutputStream.flush();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private ObjectInputStream objectInputStream;
	private ObjectOutputStream objectOutputStream;
	public void initialize() {
		try {
			/**
			 * According to the documentation the constructor of the ObjectInputStream 
			 * will block until it gets the version and the magic number from the 
			 * header written over an ObjectOutputStream. In order not to get a 
			 * deadlock you should always first create the ObjectOutputStream and flush 
			 * it before creating the ObjectInputStream. You should do this on both 
			 * sides of a full duplex connection.
			 */
			objectOutputStream = new ObjectOutputStream(outputStream);
			objectOutputStream.flush();
			objectInputStream = new ObjectInputStream(inputStream);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	
	public SerializableStreamStrategy(Socket socket) {
		try {
			setInputStream(socket.getInputStream());
			setOutputStream(socket.getOutputStream());
			
			initialize();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	
	public SerializableStreamStrategy() {
		// Default constructor
	}

}
